package com.txc.cloud.admin.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.txc.cloud.admin.entity.DeptEntity;
import com.txc.cloud.admin.mapper.DeptMapper;
import com.txc.cloud.admin.model.dto.DeptDto;
import com.txc.cloud.admin.service.IDeptService;
import com.txc.common.utils.format.ObjectFormat;
import com.txc.common.utils.middleware.RedisUtils;
import com.txc.common.utils.structure.tree.ConvertTree;
import com.txc.common.utils.structure.tree.Tree;
import com.txc.common.utils.structure.tree.TreeNode;
import com.txc.openfeign.common.admin.vo.DeptVo;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

import static com.txc.cloud.admin.common.constant.CacheKeyConstant.ADMIN_DEPT_HASH;
import static com.txc.cloud.admin.common.constant.CacheKeyConstant.generateKey;

/**
 * @ClassName: IDeptServiceImpl
 * @Author: TXC
 * @Date: 2022-08-14 10:23
 **/
@Service
public class DeptServiceImpl extends ServiceImpl<DeptMapper, DeptEntity> implements IDeptService {
    @Resource
    private RedisUtils redisUtils;

    @Override
    public List<TreeNode<DeptVo>> getDeptAndChild(Long id) {
        List<DeptVo> deptList;
        List<Object> deptCache = redisUtils.hashValues(generateKey(ADMIN_DEPT_HASH));
        if (ObjectUtil.isNotEmpty(deptCache)) {
            deptList = deptCache.stream().map(item ->
                    ObjectFormat.objToObject(item, DeptVo.class)
            ).collect(Collectors.toList());
        } else {
            deptList = baseMapper.getDeptAndChild();
            redisUtils.hashSet(generateKey(ADMIN_DEPT_HASH), deptList.stream().collect(Collectors.toMap(DeptVo::getId
                    , item -> item)));
        }
        ConvertTree<DeptVo> convertTree = new ConvertTree<>();
        Tree<DeptVo> tree = convertTree.getForest(deptList);
        if (ObjectUtil.isEmpty(id)) {
            return tree.getTreeRoot();
        }
        List<TreeNode<DeptVo>> res = new ArrayList<>();
        TreeNode<DeptVo> deptNode = tree.getNodeById(id);
        res.add(deptNode);
        return res;
    }

    @Override
    public boolean createOrUpdate(DeptDto dept) {
        boolean res = false;
        if (ObjectUtil.isNotEmpty(dept)) {
            DeptEntity deptEntity = new DeptEntity();
            BeanUtils.copyProperties(dept, deptEntity);
            if (ObjectUtil.isEmpty(deptEntity.getId())) {
                res = deptEntity.insert();
                flushRedis(deptEntity);
            } else {
                redisUtils.hashDel(generateKey(ADMIN_DEPT_HASH), deptEntity.getId());
                res = deptEntity.updateById();
                flushRedis(deptEntity);
            }
        }
        return res;
    }

    /**
     * 刷新缓存
     * @param deptEntity 部门实体
     */
    private void flushRedis(DeptEntity deptEntity) {
        List<Object> deptCache = redisUtils.hashValues(generateKey(ADMIN_DEPT_HASH));
        if (ObjectUtil.isNotEmpty(deptCache)) {
            DeptVo deptVo = new DeptVo();
            deptVo.setId(deptEntity.getId());
            deptVo.setName(deptEntity.getName());
            deptVo.setParentId(deptEntity.getParentId());
            deptVo.setStatus(deptEntity.getStatus());
            redisUtils.hashSet(generateKey(ADMIN_DEPT_HASH), deptEntity.getId(), deptVo);
        }
    }
}
